//
//  MPBNetWorking.h
//  MiaoPai
//
//  Created by jiaxuzhou on 2017/5/24.
//  Copyright © 2017年 jiaxuzhou. All rights reserved.
//


#import <Foundation/Foundation.h>
#import "MPBNetWorkBase.h"
#import "MPSHandleSessionManager.h"

@class MPBNetWorking;


void _mpqueue_block_async_on_networing_operate_queue(dispatch_block_t block);
/*!
 *  @brief 异步网络请求的回调类型，成功和失败都使用该类型，除了同步请求回调、类方法的请求回调，都使用该回调类型
 *
 *  @param netWork 发起请求的实例对象
 *  @param operation 执行请求任务的任务对象
 */
typedef void (^MPHNetFinishedBlock)(MPBNetWorking *netWork, MPURLSessionTask *operation);

/// 缓存回调
typedef void (^MPHNetCatcheBlock)(NSDictionary *dicData);

/*!
 *  @brief 同步请求的回调类型
 *
 *  @param netWork 执行请求的实例对象
 *  @param responseObject 请求结果
 */
typedef void (^MPHNetFinishedBlock4Sync)(MPBNetWorking *netWork, id responseObject);

/*!
 *  @brief 类方法请求的回调
 *
 *  @param operation 执行请求任务的任务对象
 *  @param responseObject 请求结果
 */
typedef void (^MPHNetFinishedBlockStatic)(MPURLSessionTask *operation, id responseObject);


/**
 无网络回调

 @return 是否底层显示无网络提示
 */
typedef BOOL(^MPHNoNetWorkBlock)(void);

typedef BOOL(^MPHNoNetWorkNewBlock)(MPBNetWorking *netWork);


@protocol MPBNetWorking <NSObject>

@optional

/**
 *
 *  当该请求有固定用途时，以下方法可以在子类中重写
 */

/**
 请求url path 统一不传域名 例如 m/appChackH5.json

 @return path
 */
- (NSString *)netWorkURL;

/**
 业务参数

 @return 业务参数
 */
- (NSDictionary *)netWorkParameters;

/**
 需要单独覆盖公共的header参数

 @return header参数
 */
- (NSDictionary *)netWorkHeaderCommentParameter;

/**
 需要单独覆盖公共的body参数

 @return 需要单独覆盖公共的body参数
 */
- (NSDictionary *)netWorkBodyCommentParameter;

/**
 请求类型 POST GET

 @return 请求类型 POST GET
 */
- (MPE_NetMethod)requestMethod;

/**
 解析类型

 @return 解析类型
 */
- (MPE_NetResponseType)responseType;

/**
 网络请求成功回调
 */
- (void)netWorkSuccessPreHandle;

/**
 网络请求失败回调
 */
- (void)netWorkFailedPreHandle;

/**
 网络请求读取缓存回调
 */
- (void)netWorkCachePreHandle;


@end


@interface MPBNetWorking : NSObject <MPBNetWorking>


#pragma mark - 可初始化参数

/***************************************************************************************************
 *  初始化参数
 ***************************************************************************************************/

/// 会话过期会回调此block
@property (nonatomic, copy) void (^sessionTimeoutBlock)(MPE_NetWorkSessionState state);

/// 没有网络回调此block 不会发送请求，不会回调失败block   返回是否底层弹无网提示 YES 底层弹  NO 不弹
@property (nonatomic, copy) MPHNoNetWorkBlock noNetWorkBlock;

/// 网络请求失败时是否需要弹框提示。YES（默认）有弹框提示；NO 无弹框提示
@property (nonatomic, assign) BOOL isShowToastView4NetWorkState;

/// 设置唯一ID
@property (nonatomic, strong) id uniqueID;

/// 独立设置超时时间
@property (nonatomic, assign) CGFloat timeoutInterval;

/// 设置task优先级
@property (nonatomic, assign) MPE_NetWorkPriority priority;


#pragma mark - 可获取的结果内容 Response

/***************************************************************************************************
 *  可获取的结果内容
 ***************************************************************************************************/

/// 请求返回结构
@property (nonatomic, strong) id responseObject;

/// 请求返回结构，原始值
@property (nonatomic, strong) id originalData;

/// 缓存数据
@property (nonatomic, strong) id cacheData;

/// 新旧api替换
@property (nonatomic, assign) BOOL oldApi;
/// 设置response加密方式
@property (nonatomic, assign) MPE_NetRespSecType responseSecType;

@property (nonatomic, assign) BOOL reqByTotalUrl;

#pragma mark - 对网络请求的操作方法 handle

/***************************************************************************************************
 *  操作方法
 ***************************************************************************************************/

- (instancetype)initWithApi:(BOOL)isoldApi;

/**
 取消当前网络请求
 */
- (void)cancelSelf;

/**
 取消全部网络请求
 */
+ (void)cancelAllRequest;

/**
 根据URL取消网络请求

 @param url url
 */
+ (void)cancelRequestWithURL:(NSString *)url;

+ (NSUInteger)tasksCount;

+ (NSMutableArray *)allTasks;

- (MPURLSessionTask *)getSelfTask;


#pragma mark - 普通网络请求方法 request

/***************************************************************************************************
 *  普通网络请求方法，用于GET、POST请求
 ***************************************************************************************************/

/*!
 *
 *  @param method           MPE_NetMethod 类型，默认 POST
 *  @param inView           显示loading框的视图，默认 nil
 *  @param url              请求地址，默认会从继承方法中调取；传入地址优先调用
 *  @param dictParams       请求参数字典
 *  @param success          请求成功回调
 *  @param failed           请求失败回调
 *
 */

/// (异步)创建对象: 参数最少
- (void)netWorkWithsuccess:(MPHNetFinishedBlock)success
                           failed:(MPHNetFinishedBlock)failed
                            cached:(void (^)(NSDictionary *cachedObject))cached;

- (void)netWorkWithsuccess:(MPHNetFinishedBlock)success
                    failed:(MPHNetFinishedBlock)failed
                 noNetWork:(MPHNoNetWorkNewBlock)noNetWork
                    cached:(void (^)(NSDictionary *cachedObject))cached;
/// (异步)创建对象: 参数最全的

/**
 (异步)创建对象: 参数最全的

 @param method 请求方式 POST GET
 @param url path （不含）
 @param dictParams 业务参数
 @param isShowNoNetAlert 是否显示无网络提示
 @param isEncrypt 参数是否加密
 @param success 成功回调
 @param failed 失败回调
 @param cached 缓存数据
 */
- (void)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
                 isShowNoNetAlert:(BOOL)isShowNoNetAlert
                        isEncrypt:(BOOL)isEncrypt
                          success:(MPHNetFinishedBlock)success
                           failed:(MPHNetFinishedBlock)failed
                           cached:(void (^)(NSDictionary *cachedObject))cached;

- (void)netWorkWithMethod:(MPE_NetMethod)method
                      URL:(NSString *)url
                   params:(NSDictionary *)dictParams
         isShowNoNetAlert:(BOOL)isShowNoNetAlert
                isEncrypt:(BOOL)isEncrypt
                  success:(MPHNetFinishedBlock)success
                   failed:(MPHNetFinishedBlock)failed
                noNetWork:(MPHNoNetWorkNewBlock)noNetWork
                   cached:(void (^)(NSDictionary *cachedObject))cached;


#pragma mark - 上传文件网络请求方法

/***************************************************************************************************
 *  上传文件网络请求方法
 ***************************************************************************************************/

/**
  (异步)上传文件网络请求方法: 参数最少

 @param uploadFile NSInputStream 流
 @param success 成功回调
 @param failed 失败回调
 */
- (void)netWorkUploadFile:(id)uploadFile
                          success:(MPHNetFinishedBlock)success
                          failure:(MPHNetFinishedBlock)failed;

/**
 (异步)上传文件网络请求方法: uploadFile  destUrl  parameters

 @param uploadFile NSInputStream 流
 @param destUrl 服务器url
 @param parameters 参数
 @param success 成功回调
 @param failed 失败回调
 */
- (void)netWorkUploadFile:(id)uploadFile
                          destUrl:(NSString *)destUrl
                       parameters:(NSDictionary *)parameters
                          success:(MPHNetFinishedBlock)success
                          failure:(MPHNetFinishedBlock)failed;

/**
 (异步)上传文件网络请求方法: uploadFile fileName parameters

 @param uploadFile NSInputStream 流
 @param fileName 服务器接收的文件名字
 @param parameters 参数
 @param success 成功回调
 @param failed 失败回调
 */
- (void)netWorkUploadFile:(id)uploadFile
                         fileName:(NSString *)fileName
                       parameters:(NSDictionary *)parameters
                          success:(MPHNetFinishedBlock)success
                          failure:(MPHNetFinishedBlock)failed;

/**
 (异步)上传文件网络请求方法: uploadFile destUrl parameters

 @param uploadFile NSInputStream 流
 @param destUrl 服务器url
 @param fileName 服务器接收的文件名字
 @param parameters 参数
 @param success 成功回调
 @param failed 失败回调
 */
- (void)netWorkUploadFile:(id)uploadFile
                          destUrl:(NSString *)destUrl
                         fileName:(NSString *)fileName
                       parameters:(NSDictionary *)parameters
                          success:(MPHNetFinishedBlock)success
                          failure:(MPHNetFinishedBlock)failed;

/**
 (异步)上传文件网络请求方法: uploadFile length destUrl fileName

 @param uploadFile NSInputStream 流
 @param length 文件长度
 @param destUrl 服务器url
 @param fileName 服务器接收的文件名字
 @param parameters 参数
 @param success 成功回调
 @param failed 失败回调
 */
- (void)netWorkUploadFile:(id)uploadFile
                           length:(int64_t)length
                          destUrl:(NSString *)destUrl
                         fileName:(NSString *)fileName
                       parameters:(NSDictionary *)parameters
                          success:(MPHNetFinishedBlock)success
                          failure:(MPHNetFinishedBlock)failed;

/**
 (异步)上传文件网络请求方法: uploadFile length destUrl paramFileName fileName parameters

 @param uploadFile NSInputStream 流
 @param length 文件长度
 @param destUrl 服务器url
 @param paramFileName 要保存在服务器上的[文件名]
 @param fileName 服务器接收的文件名字
 @param parameters 参数
 @param isEncrypt 参数是否加密
 @param success 成功回调
 @param failed 失败回调
 */
- (void)netWorkUploadFile:(id)uploadFile
                           length:(int64_t)length
                          destUrl:(NSString *)destUrl
                    paramFileName:(NSString *)paramFileName
                         fileName:(NSString *)fileName
                       parameters:(NSDictionary *)parameters
                        isEncrypt:(BOOL)isEncrypt
                          success:(MPHNetFinishedBlock)success
                          failure:(MPHNetFinishedBlock)failed;

/**
 (异步)上传文件网络请求方法: destUrl parameters AFMultipartFormData

 @param destUrl 服务器url
 @param parameters 参数
 @param isEncrypt 参数是否加密
 @param block AFMultipartFormData 流
 @param success 成功回调
 @param failed 失败回调
 */
- (void)netWorkUploadFileTo:(NSString *)destUrl
                         parameters:(NSDictionary *)parameters
                          isEncrypt:(BOOL)isEncrypt
          constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
                            success:(MPHNetFinishedBlock)success
                            failure:(MPHNetFinishedBlock)failed;



#pragma mark - 同步网络请求方法

/***************************************************************************************************
 *  同步网络请求方法
 ***************************************************************************************************/

/**
 (同步)创建对象: 唯一方法

 @param method 请求方式
 @param url 服务器url
 @param dictParams 参数
 @param isShowNoNetAlert 是否显示无网络提示
 @param isEncrypt 是否加密
 @param success 成功回调
 @param failed 失败回调
 @param cached 缓存
 @return 网络请求返回的结果数据
 */
- (id)netWorkSyncWithMethod:(MPE_NetMethod)method
                        URL:(NSString *)url
                     params:(NSDictionary *)dictParams
           isShowNoNetAlert:(BOOL)isShowNoNetAlert
                  isEncrypt:(BOOL)isEncrypt
                    success:(MPHNetFinishedBlock4Sync)success
                     failed:(MPHNetFinishedBlock4Sync)failed
                     cached:(void (^)(NSDictionary *cachedObject))cached;


#pragma mark - 类方法 - 普通网络请求方法

/***************************************************************************************************
 *  类方法 - 普通网络请求方法
 ***************************************************************************************************/

/**
 *  
 *  直接调用，不需要创建对象，请求对象的管理由系统完成
 */

/**
 (异步)类方法: 参数最少

 @param method 请求方式
 @param url 服务器url
 @param dictParams 参数
 @param success 成功回调
 @param failed 失败回调
 @return 当前MPBNetWorking对象
 */
+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed;

+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
                           oldApi:(BOOL)oldApi
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed;
/**
 (异步)类方法: 无网提示

 @param method 请求方式
 @param url 服务器url
 @param dictParams 参数
 @param isShowNoNetAlert 是否显示无网络提示
 @param success 成功回调
 @param failed 失败回调
 @return 当前MPBNetWorking对象
 */
+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
                 isShowNoNetAlert:(BOOL)isShowNoNetAlert
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed;

/**
 (异步)类方法: toast提示

 @param method 请求方式
 @param url 服务器url
 @param dictParams 参数
 @param isShowToastView4NetWorkState 是否提示错误信息
 @param success 成功回调
 @param failed 失败回调
 @return 当前MPBNetWorking对象
 */
+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
     isShowToastView4NetWorkState:(BOOL)isShowToastView4NetWorkState
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed;

/**
 (异步)类方法: 缓存

 @param method 请求方式
 @param priority 优先级
 @param url 服务器url
 @param dictParams 参数
 @param success 成功回调
 @param failed 失败回调
 @param cached 缓存回调
 @return 当前MPBNetWorking对象
 */
+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                         priority:(MPE_NetWorkPriority)priority
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed
                           cached:(void (^)(NSDictionary *cachedObject))cached;

/**
 (异步)类方法: 无网提示，缓存

 @param method 请求方式
 @param url 服务器url
 @param dictParams 参数
 @param isShowNoNetAlert 是否显示无网络提示
 @param priority 优先级
 @param success 成功回调
 @param failed 失败回调
 @param cached 缓存回调
 @return 当前MPBNetWorking对象
 */
+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
                 isShowNoNetAlert:(BOOL)isShowNoNetAlert
                         priority:(MPE_NetWorkPriority)priority
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed
                           cached:(void (^)(NSDictionary *cachedObject))cached;

/**
 (异步)类方法: toast提示，缓存

 @param method 请求方式
 @param url 服务器url
 @param dictParams 参数
 @param isShowToastView4NetWorkState 是否提示错误信息
 @param priority 优先级
 @param success 成功回调
 @param failed 失败回调
 @param cached 缓存回调
 @return 当前MPBNetWorking对象
 */
+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
     isShowToastView4NetWorkState:(BOOL)isShowToastView4NetWorkState
                         priority:(MPE_NetWorkPriority)priority
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed
                           cached:(void (^)(NSDictionary *cachedObject))cached;

/**
 (异步)类方法: 无网提示，toast

 @param method 请求方式
 @param url 服务器url
 @param dictParams 参数
 @param isShowNoNetAlert 是否显示无网络提示
 @param isShowToastView4NetWorkState 是否提示错误信息
 @param priority 优先级
 @param success 成功回调
 @param failed 失败回调
 @return 当前MPBNetWorking对象
 */
+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
                 isShowNoNetAlert:(BOOL)isShowNoNetAlert
     isShowToastView4NetWorkState:(BOOL)isShowToastView4NetWorkState
                         priority:(MPE_NetWorkPriority)priority
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed;

/**
 (异步)类方法: 无网提示，toast提示，缓存

 @param method 请求方式
 @param url 服务器url
 @param dictParams 参数
 @param isShowNoNetAlert 是否显示无网络提示
 @param isShowToastView4NetWorkState 是否提示错误信息
 @param priority 优先级
 @param success 成功回调
 @param failed 失败回调
 @param cached 缓存回调
 @return 当前MPBNetWorking对象
 */
+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
                 isShowNoNetAlert:(BOOL)isShowNoNetAlert
     isShowToastView4NetWorkState:(BOOL)isShowToastView4NetWorkState
                         priority:(MPE_NetWorkPriority)priority
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed
                           cached:(void (^)(NSDictionary *cachedObject))cached;

/**
 (异步)类方法: 参数最全的

 @param method 请求方式
 @param url 服务器url
 @param dictParams 参数
 @param isShowNoNetAlert 是否显示无网络提示
 @param isShowToastView4NetWorkState 是否提示错误信息
 @param timeoutInterval 超时时间
 @param isEncrypt 参数是否加密
 @param priority 优先级
 @param success 成功回调
 @param failed 失败回调
 @param cached 缓存回调
 @param sessiontimeout session过期
 @return 当前MPBNetWorking对象
 */
+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
                 isShowNoNetAlert:(BOOL)isShowNoNetAlert
     isShowToastView4NetWorkState:(BOOL)isShowToastView4NetWorkState
                  timeoutInterval:(CGFloat)timeoutInterval
                        isEncrypt:(BOOL)isEncrypt
                         priority:(MPE_NetWorkPriority)priority
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed
                           cached:(void (^)(NSDictionary *cachedObject))cached
                   sessionTimeOut:(void (^)(MPE_NetWorkSessionState state))sessiontimeout;

+ (instancetype)netWorkWithMethod:(MPE_NetMethod)method
                              URL:(NSString *)url
                           params:(NSDictionary *)dictParams
                 isShowNoNetAlert:(BOOL)isShowNoNetAlert
     isShowToastView4NetWorkState:(BOOL)isShowToastView4NetWorkState
                  timeoutInterval:(CGFloat)timeoutInterval
                        isEncrypt:(BOOL)isEncrypt
                           oldApi:(BOOL)oldApi
                         priority:(MPE_NetWorkPriority)priority
                          success:(MPHNetFinishedBlockStatic)success
                           failed:(MPHNetFinishedBlockStatic)failed
                           cached:(void (^)(NSDictionary *cachedObject))cached
                   sessionTimeOut:(void (^)(MPE_NetWorkSessionState state))sessiontimeout;


#pragma mark - 类方法 - 同步网络请求方法

/***************************************************************************************************
 *  (同步)类方法: 同步网络请求方法
 ***************************************************************************************************/

/**
 (同步)类方法: 参数最少

 @param url 服务器url
 @param dictParams 参数
 @param cached 缓存回调
 @return 网络请求返回的结果数据
 */
+ (id)netWorkSyncWithURL:(NSString *)url
                  params:(NSDictionary *)dictParams
                  cached:(void (^)(NSDictionary *cachedObject))cached;

/**
 (同步)类方法: 无网提示

 @param url 服务器url
 @param dictParams 参数
 @param isShowNoNetAlert 是否显示无网络提示
 @param cached 缓存回调
 @return 网络请求返回的结果数据
 */
+ (id)netWorkSyncWithURL:(NSString *)url
                  params:(NSDictionary *)dictParams
        isShowNoNetAlert:(BOOL)isShowNoNetAlert
                  cached:(void (^)(NSDictionary *cachedObject))cached;

/**
 (同步)类方法: toast提示

 @param url 服务器url
 @param dictParams 参数
 @param isShowToastView4NetWorkState 是否提示错误信息
 @param cached 缓存回调
 @return 网络请求返回的结果数据
 */
+ (id)netWorkSyncWithURL:(NSString *)url
                  params:(NSDictionary *)dictParams
isShowToastView4NetWorkState:(BOOL)isShowToastView4NetWorkState
                  cached:(void (^)(NSDictionary *cachedObject))cached;

/**
 (同步)类方法: 参数最全

 @param url 服务器url
 @param dictParams 参数
 @param isShowNoNetAlert 是否显示无网络提示
 @param isShowToastView4NetWorkState 是否提示错误信息
 @param isEncrypt 参数是否加密
 @param priority 优先级
 @param cached 缓存回调
 @return 网络请求返回的结果数据
 */
+ (id)netWorkSyncWithURL:(NSString *)url
                  params:(NSDictionary *)dictParams
        isShowNoNetAlert:(BOOL)isShowNoNetAlert
isShowToastView4NetWorkState:(BOOL)isShowToastView4NetWorkState
               isEncrypt:(BOOL)isEncrypt
                priority:(MPE_NetWorkPriority)priority
                  cached:(void (^)(NSDictionary *cachedObject))cached;


@end
